package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.file.Paths;
import java.util.HashMap;

import javax.servlet.http.HttpServletResponse;
// @RestController
@Controller
public class FileProcessController {
    private String staticPath = Paths.get("").toAbsolutePath().toString()+"/static";
    private String pdfFilePath = staticPath+"/pdfs";
    @GetMapping("/")
    public @ResponseBody ModelAndView home(){
        String indexFilePath = "html/index.html";
        ModelAndView mv = new ModelAndView(indexFilePath);
        return mv;
    }
    @GetMapping("/download")
    public void download(@RequestParam("fileName") String fileName,HttpServletResponse response) throws IOException{
        String targetPath ;
        String fileNameEncode;
        try {
            fileNameEncode = URLEncoder.encode(fileName,"UTF-8");
            //替换+号否则空格解析会出错            
            fileNameEncode = fileNameEncode.replaceAll("\\+", "%20");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            fileNameEncode = "";
        }
        targetPath = String.join("/",staticPath,fileName);
        File downloadFile = new File(targetPath);
        FileInputStream downFileInputStream = new FileInputStream(downloadFile);
        InputStream returnStream  = new BufferedInputStream(downFileInputStream);
        byte[] buffer = new byte[returnStream.available()];
        System.out.println("download:"+targetPath);
        System.out.println("file exist:"+new File(Paths.get(String.join("/", staticPath,fileName)).toAbsolutePath().toString()).exists());
        returnStream.read(buffer);
        returnStream.close();
        response.reset();
        //设置response的Header
        response.setCharacterEncoding("UTF-8");
        //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
        //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
        //filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
        response.addHeader("Content-Disposition", "attachment;filename=" + fileNameEncode);
        //告知浏览器文件的大小
        response.addHeader("Content-Length", "" + downloadFile.length());
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        response.setContentType("application/octet-stream");
        outputStream.write(buffer);
        outputStream.flush();
    }
    @GetMapping("/preview")
    public ModelAndView preview(@RequestParam("fileName") String fileName) throws Exception{
        String targetPath ;
        String fileNameEncode = Utils.getUrlEncode(fileName);
        String fileSuffix = Utils.getFileSuffix(fileName);
        targetPath = String.join("/",fileNameEncode);
        System.out.println("preview:"+fileName+" url:"+fileNameEncode);
        System.out.println("file exist:"+new File(Paths.get(String.join("/", staticPath,fileName)).toAbsolutePath().toString()).exists());
        if(fileSuffix.equals("docx")||fileSuffix.equals("doc")){

            String targetPdfFilePath = String.join("/", pdfFilePath,fileName.replace("."+fileSuffix,".pdf" ));
            File targetPdfFile = new File (targetPdfFilePath);
            String sourcePath = String.join("/", staticPath,fileName);
            if(!targetPdfFile.exists()){Utils.WordToPdf(sourcePath, targetPdfFilePath);}
            return new ModelAndView("redirect:/preview/"+String.join("/", "pdfs",Utils.getUrlEncode(fileName.replace("."+fileSuffix,".pdf" ))));
        }
        else{
            System.out.println("redirect:/preview/"+targetPath);
            return new ModelAndView("redirect:/preview/"+targetPath);
        }
    }
    // @DeleteMapping("/delete")
    @GetMapping("/delete")
    public String delete(@RequestParam("fileName") String fileName) throws IOException{
        File deleteFile = new File(Paths.get(String.join("/", staticPath,fileName)).toAbsolutePath().toString());
        if (deleteFile.exists()){
            deleteFile.delete();
        }
        System.out.println("delete:"+deleteFile.getName());
        return "redirect:/";
    }
    @PostMapping("/upload")
    public  String upload(@RequestParam("files") MultipartFile[] files) throws Exception{
        if(files != null && files.length>0){
            for(MultipartFile file:files){
                if(!file.isEmpty()){
                        System.out.println("staticPath:"+new File(staticPath).getCanonicalPath());
                        String fileName = file.getOriginalFilename();
                        File newFile = new File(staticPath+"/"+fileName);
                        String fileSuffix = Utils.getFileSuffix(fileName);
                        System.out.println("save:"+newFile.getCanonicalPath()+" suffix:"+fileSuffix);
                        if(!new File(newFile.getParent()).exists()){
                            System.out.println("make dirs:"+newFile.getParent());
                            new File(newFile.getParent()).mkdirs();
                        }
                        if (newFile.exists()){
                            newFile.delete();
                        }
                        try{
                            file.transferTo(newFile);
                        }
                        catch(UnsupportedEncodingException e){
                            System.out.println("error:"+fileName);
                        }
                        if(fileSuffix.equals("docx")||fileSuffix.equals("doc")){
                            String targetPdfFilePath = String.join("/",pdfFilePath,fileName.replace("."+fileSuffix,".pdf"));
                            File targetPdfFile = new File(targetPdfFilePath);
                            if(!new File(pdfFilePath).exists()){
                                System.out.println("make dirs:"+pdfFilePath);
                                new File(pdfFilePath).mkdirs();
                            }
                            if(targetPdfFile.exists()){targetPdfFile.delete();}
                            System.out.println("transform to pdf:");
                            Utils.WordToPdf(newFile.getCanonicalPath(),targetPdfFilePath);
                            // PdfHelper3.doc2pdf(newFile.getCanonicalPath(),targetPdfFilePath);
                        }
                    }
                }
        }
        return "redirect:/";
        
    }
    @GetMapping("/getFileList")
    public @ResponseBody String[] getFileList() throws IOException{
        HashMap<String,String> fileMap = new HashMap<String,String>();
        File staticFile = new File(staticPath);
        System.out.println("静态文件夹:"+staticFile.getCanonicalPath());
        if (staticFile!=null && staticFile.isDirectory())
        {
            File[] fileList = staticFile.listFiles();
            for(int i=0;i<fileList.length;i++){
                String fileName = fileList[i].getName();
                // fileNameList[i] = fileName;
                if(new File(String.join("/",staticPath,fileName)).isFile()){
                    fileMap.put(fileName,String.valueOf(i));
                }
            }
            // String[] fileNameList = new String[fileList.length]; 
            String[] fileNameList = new String[fileMap.keySet().size()]; 
            fileMap.keySet().toArray(fileNameList);
            return fileNameList ;
            // return fileMap.keySet();
        }
        else{
            String[] fileNameList = new String[0]; 
            return fileNameList;
        }
    } 
}
